#include "QtTutorialApp5.h"
#include <QPainter>
#include <Graphics/Keyboard/QtKeyboard/QtKeyboard.h>
#include <Utility/Config.h>

#ifdef WIN32
#ifdef QtTutorial5_EXPORTS
#define QTTUTORIAL5_API __declspec(dllexport)
#else
#define QTTUTORIAL5_API __declspec(dllimport)
#endif
#else
#define QTTUTORIAL5_API
#endif

extern "C" QTTUTORIAL5_API Blobz::QtBaseApplication* GetInstance()
{
	QtTutorial5::QtTutorial5App* pTutorial = new QtTutorial5::QtTutorial5App();
	return pTutorial;
}

extern "C" QTTUTORIAL5_API unsigned int GetMajorReleaseVersion()
{
	return NUI_RELEASE_MAJOR_VER;
}

extern "C" QTTUTORIAL5_API unsigned int GetMinorReleaseVersion()
{
	return NUI_RELEASE_MINOR_VER;
}

extern "C" QTTUTORIAL5_API bool IsQtApp()
{
	return true;
}

extern "C" QTTUTORIAL5_API const char* GetAppName()
{
	return "QtTutorial5";
}

namespace QtTutorial5
{
	/**
	* Constructor
	*/
	QtTutorial5App::QtTutorial5App() :
		mCurrentScale(1),
		mpTextItem(NULL),
		mpKeyboard(NULL),
		mBackground()
	{
		// Connect the size change signal to the handling method.
		connect(this, SIGNAL(maximizedChanged(bool)), SLOT(onItemsSizeSetup()));
	}

	/**
	* Destructor
	*/
	QtTutorial5App::~QtTutorial5App()
	{
	}

	/**
	* Loads the objects and the text view
	*/
	bool QtTutorial5App::onInitialize()
	{
		// Loads the image
		bool success = mBackground.load(getApplicationDirectory()+"bg.png");

		// Initialize the text view
		mpTextItem = new MyTextItem(this);

		m_pWebView = new QWebView();
		//set position and size
		m_pWebView->setGeometry(5,30,1450,720);
		m_pWebView->load(QUrl("http://www.streetdirectory.com/"));
		m_pWebView->show();

		// Setup the keyboard
		mpKeyboard = new Blobz::QtKeyboard(this);
		mpKeyboard->load(QString("../data/Keyboard/gfx/"), QString("../data/Keyboard/layouts/layout_")+getLocale()+QString(".xml"));
		mpKeyboard->setScaleLimits(1.0f, 2.5f);
		mpKeyboard->setScale(1);

		// Here we use the convenience method setLockedToArea to prevent the keyboard from leaving the 
		// screen. The reason why we don't do this all the time is because it doesn't exist for ordinary 
		// Blobz::Interactables and because 1) it works out of the items position rather then its center 
		// (thereof the adjustment below) and 2) because it does not take rotation or scale into account. 
		// The non-handling of scale will still cause it to be possible to push a scaled keyboard partially 
		// outside of the screen but because the rotation of Blobz::KeyboardWidget is disabled per default 
		// that at least won't cause problems.
		mpKeyboard->setLockedToArea(QRectF(QPointF(0, 0), getWindowSize() - mpKeyboard->boundingRect().size()));

		// Set the position of the keyboard
		QPointF kbdPos(getWindowSize().width()*0.5-mpKeyboard->boundingRect().width()*0.5, getWindowSize().height()*0.5f);
		mpKeyboard->setPos(kbdPos);				

		// Register the text view as an listener to the keyboard events
		//mpKeyboard->addListener(mpTextItem);
		 mpKeyboard->addListener(m_pWebView);

		return true;
	}
	
	/**
	* Unload all objects
	*/
	void QtTutorial5App::onDeinitialize()
	{
		if(mpKeyboard != NULL)
		{
			mpKeyboard->unload();
			delete mpKeyboard;
			mpKeyboard = NULL;
		}

		if(mpTextItem != NULL)
			delete mpTextItem;
	}

	/**
	* Triggered on every frame update
	* \param inFrameTime Time since last update ( in seconds )
	*/
	void QtTutorial5App::onUpdate( float inFrameTime )
	{
		mpKeyboard->onUpdate(inFrameTime);

		// Set the position of the Text Field to be at the center of x-axis
		QSizeF textSize = mpTextItem->boundingRect().size();
		mpTextItem->setPos((getWindowSize().width()-textSize.width())*0.5f, 200.f);
		
	}

	/**
	* Event handlers
	* \param inEvent Holds the event information
	* \return bool 
	*/
	bool QtTutorial5App::onEvent( QEvent *inEvent )
	{
		// This program didn't handle the event, so return false
		return false;
	}

	/**
	* Triggered when there is a finger down event on the screen
	* \param inData holds the touch information
	*/
	void QtTutorial5App::onFingerDown( const TouchListener::TouchData& inData )
	{
		mpKeyboard->onFingerDown(inData);
	}

	/**
	* Triggered when there is a finger up event on the screen
	* \param inData holds the touch information
	*/
	void QtTutorial5App::onFingerUp( const TouchListener::TouchData& inData )
	{
		mpKeyboard->onFingerUp(inData);
	}

	/**
	* Triggered when there is a finger update event on the screen
	* \param inData holds the touch information
	*/
	void QtTutorial5App::onFingerUpdate( const TouchListener::TouchData& inData )
	{
		mpKeyboard->onFingerUpdate(inData);
	}

	/**
	* Triggered when there is a finger moves out of the screen or application window
	* \param inData holds the touch information
	*/
	void QtTutorial5App::onFingerExit( const TouchListener::TouchData& inData )
	{
		// just treat finger exit events as finger up events
		onFingerUp(inData);
	}

	/**
	* Render method
	* \param inpPainter QT Rendering system pointer
	* \param inpOption Pointer to various rendering options
	* \param inpWidget Pointer to Parent Widget
	*/
	void QtTutorial5App::paint( QPainter* inpPainter, const QStyleOptionGraphicsItem *inpOption, QWidget *inpWidget )
	{
		// Render the background
		inpPainter->drawImage(QRectF(QPointF(0, 0), getWindowSize()), mBackground);
		
		// Set our requested font to Verdana, font size 20
		inpPainter->setFont(QFont("Verdana", 20));
		// Set the brush color to black
		inpPainter->setPen(Qt::black);

		// Render the title
		QString mainText = "Type using the virtual keyboard.";
		QSize textSize = inpPainter->fontMetrics().size(Qt::TextSingleLine, mainText);
		inpPainter->drawText((getWindowSize().width()-textSize.width())*0.5f, 100 * scale(), textSize.width(), textSize.height(), Qt::AlignCenter, mainText);
		mpKeyboard->setVisible(true);
	}
	
	/**
	* Rescale and reposition items.
	*/
	void QtTutorial5App::onItemsSizeSetup()
	{
		float naturalScale = scale();
		float scaleChange = naturalScale / mCurrentScale;

		if(mpTextItem)
		{
			// We leave the text box at the same scale in the interest of being easily readable.
			QSizeF textSize = mpTextItem->boundingRect().size();
			mpTextItem->setPos((getWindowSize().width()-textSize.width())*0.5f, 200.f * naturalScale);
		}
		if(mpKeyboard)
		{
			mpKeyboard->setPos(mpKeyboard->pos() * scaleChange);
			mpKeyboard->setLockedToArea(QRectF(QPointF(0, 0), getWindowSize() - mpKeyboard->boundingRect().size()));
		}

		mCurrentScale = naturalScale;
	}
}

